package com.runjian.rundo.iot.agent.common.network.tcp.handle;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.runjian.rundo.bmp.kernel.common.spring.context.utils.MdcUtils;
import com.runjian.rundo.iot.agent.business.publisher.DeviceMessagePublisher;
import com.runjian.rundo.iot.agent.common.codec.DeviceMessageCodec;
import com.runjian.rundo.iot.agent.common.context.DeviceMessageDecodeContext;
import com.runjian.rundo.iot.agent.common.message.DeviceMessage;
import com.runjian.rundo.iot.agent.common.network.tcp.config.ChannelAttributes;
import com.runjian.rundo.iot.agent.common.network.tcp.message.TcpMessage;
import com.runjian.rundo.iot.agent.common.network.tcp.session.TcpDeviceSession;
import com.runjian.rundo.iot.agent.common.network.tcp.session.TcpDeviceSessionManager;
import com.runjian.rundo.iot.agent.common.session.Session;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * tcp 字节流消息处理器
 *
 * @author CaoQingHua
 */
public interface MessageHandler{

    /**
     * 配置traceId
     *
     * @param ctx 全局上下文
     */
    default void configTraceId(ChannelHandlerContext ctx) {
        // 获取连接ID
        String connectionId = ctx.channel().attr(ChannelAttributes.CONNECTION_ID).get();
        if (StrUtil.isEmpty(connectionId)) {
            connectionId = this.configConnectionId(ctx.channel());
        }
        configTraceId(ctx.channel(), connectionId);
    }

    default void configTraceId(Channel channel, String connectionId) {
        String channelId = channel.id().asLongText();
        if (Objects.nonNull(connectionId) && !connectionId.equals(channelId)) {
            MdcUtils.setTraceId(StrUtil.format("{}_{}_{}", connectionId, channelId,
                    DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_MS_PATTERN)));
        } else {
            // 直接管道Id
            MdcUtils.setTraceId(StrUtil.format("{}_{}", channelId, DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_MS_PATTERN)));
        }
    }


    /**
     * 配置连接Id
     *
     * @param channel 管道
     * @return 连接Id
     */
    default String configConnectionId(Channel channel) {
        String id = channel.id().asLongText();
        channel.attr(ChannelAttributes.CONNECTION_ID).set(id);
        return id;
    }

}
